﻿#define _CRT_SECURE_NO_WARNINGS 1
(初阶版本)
给定一个已排序的链表的头 head ， 删除所有重复的元素，使每个元素只出现一次 。返回 已排序的链表 。



示例 1：


输入：head = [1, 1, 2]
输出：[1, 2]
示例 2：


输入：head = [1, 1, 2, 3, 3]
输出：[1, 2, 3]


提示：

链表中节点数目在范围[0, 300] 内
- 100 <= Node.val <= 100
题目数据保证链表已经按升序 排列

来源：力扣（LeetCode）
链接：https ://leetcode-cn.com/problems/remove-duplicates-from-sorted-list

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* deleteDuplicates(struct ListNode* head) {
    if (head == NULL)
        return head;
    struct ListNode* cur = head->next;
    struct ListNode* prev = head;

    while (cur)
    {
        struct ListNode* next = cur->next;

        if (cur->val == prev->val)
        {
            prev->next = next;
            free(cur);
        }
        else
        {
            prev = cur;
        }
        cur = next;
    }
    return head;

}


(进阶)
82. 删除排序链表中的重复元素 II
给定一个已排序的链表的头 head ， 删除原始链表中所有重复数字的节点，只留下不同的数字 。返回 已排序的链表 。



示例 1：


输入：head = [1, 2, 3, 3, 4, 4, 5]
输出：[1, 2, 5]
示例 2：


输入：head = [1, 1, 1, 2, 3]
输出：[2, 3]


提示：

链表中节点数目在范围[0, 300] 内
- 100 <= Node.val <= 100
题目数据保证链表已经按升序 排列


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


    struct ListNode* deleteDuplicates(struct ListNode* head) {
    if (head == NULL || head->next == NULL)
        return head;
    //由于头结点可能会发生变化，故建立一个哨兵位，就不需要改头
    struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
    dummy->next = head;
    struct ListNode* prev = dummy;
    struct ListNode* cur = head;
    while (cur && cur->next)// // cur->next：当下面的if语句中next是空指针时，避免空指针的解引用
    {
        struct ListNode* next = cur->next;
        if (cur->val == next->val)
        {
            //跳过重复数字的节点，next是重复节点区间的下一个节点
            while (next != NULL && cur->val == next->val)//// next：避免next最后是空指针，比如链表为[1,1]
            {
                next = next->next;
            }
            //连接
            prev->next = next;
            //删数字相同的结点
            while (cur != next)
            {
                struct ListNode* tmp = cur->next;
                free(cur);
                cur = tmp;
            }

        }
        else
        {
            prev = cur;
            cur = next;
        }
    }
    head = dummy->next;
    free(dummy);
    dummy = NULL;
    return head;

}
